package cn.edu.jxau.core.util;

import cn.edu.jxau.core.Constant;
import cn.edu.jxau.core.exception.DatabaseException;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.Map;

/**
 * Desc:
 * ------------------------------------
 * Author:fulei04@meituan.com
 * Date:2017/12/14
 * Time:下午7:41
 */
public class DBUtils {

    private static final QueryRunner QUERY_RUNNER = new QueryRunner();
    private static final BasicDataSource DATA_SOURCE = new BasicDataSource();

    static {

        DATA_SOURCE.setDriverClassName(Constant.JDBC_DRIVER);
        DATA_SOURCE.setUrl(Constant.JDBC_URL);
        DATA_SOURCE.setUsername(Constant.JDBC_USERNAME);
        DATA_SOURCE.setPassword(Constant.JDBC_PASSWORD);
    }

    public static Connection getConnection() {
        try {
            return DATA_SOURCE.getConnection();
        } catch (SQLException e) {
            throw new DatabaseException("获取Connection失败", e);
        }
    }

    public static void close(Connection connection, Statement statement, ResultSet resultSet) {

        try {
            if (resultSet != null) {
                resultSet.close();
            }
        } catch (SQLException e) {
            throw new DatabaseException("resultSet资源关闭失败");
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException e) {
                throw new DatabaseException("statement资源关闭失败");
            } finally {
                try {
                    if (connection != null) {
                        connection.close();
                    }
                } catch (SQLException e) {
                    throw new DatabaseException("connection资源关闭失败");
                }
            }
        }
    }

    public static <T> List<T> queryEntityList(Connection conn, Class<T> entityClass, String sql, Object... params) {

        try {
            return DBUtils.QUERY_RUNNER.query(conn, sql, new BeanListHandler<T>(entityClass), params);
        } catch (SQLException e) {
            throw new DatabaseException("查询失败", e);
        }
    }

    public static <T> T queryEntity(Connection conn, Class<T> entityClass, String sql, Object... params) {

        try {
            return DBUtils.QUERY_RUNNER.query(conn, sql, new BeanHandler<T>(entityClass), params);
        } catch (SQLException e) {
            throw new DatabaseException("查询失败", e);
        }
    }

    public static List<Map<String, Object>> queryMapList(Connection conn, String sql, Object... params) {

        try {
            return DBUtils.QUERY_RUNNER.query(conn, sql, new MapListHandler(), params);
        } catch (SQLException e) {
            throw new DatabaseException("查询失败", e);
        }
    }

    public static int updateEntity(Connection conn, String sql, Object... params) {

        try {
            return DBUtils.QUERY_RUNNER.update(conn, sql, params);
        } catch (SQLException e) {
            throw new DatabaseException("更新失败", e);
        }
    }

    public static void beginTransaction(Connection conn) {

        try {
            conn.setAutoCommit(false);
        } catch (SQLException e) {
            throw new DatabaseException("开启事务失败", e);
        }
    }

    public static void commitTransaction(Connection conn) {

        try {
            conn.commit();
        } catch (SQLException e) {
            throw new DatabaseException("提交事务失败", e);
        }
    }

    public static void rollbackTransaction(Connection conn) {

        try {
            conn.rollback();
        } catch (SQLException e) {
            throw new DatabaseException("回滚事务失败", e);
        }
    }
}
